package com.demo.java.concurrent.future.listener;

import com.demo.java.utils.ThreadUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DelayAdderTest {
    public static void main(String[] args) {
        log.info("================ main start, thread: " + ThreadUtils.threadName());
        new DelayAdder().add(3 * 1000, 1, 2).addListener(new IFutureListener<Integer>() {
            public void operationCompleted(IFuture<Integer> future) {
               log.info("=========== operation completed:, thread: " + ThreadUtils.threadName());
                log.info("==== calc result: " + future.getNow());
            }
        });
        log.info("================ main end, thread: " + ThreadUtils.threadName());
    }

    /**
     * 延时加法
     */
    static class DelayAdder {
        /**
         * 延迟加
         *
         * @paramdelay 延时时长milliseconds
         * @parama 加数
         * @paramb 加数
         * @return 异步结果
         */
        public DelayAdditionFuture add(long delay, int a, int b) {
            DelayAdditionFuture future = new DelayAdditionFuture();
            new Thread(new DelayAdditionTask(delay, a, b, future)).start();
            return future;
        }

        private class DelayAdditionTask implements Runnable {

            private long delay;

            private int a, b;

            private DelayAdditionFuture future;

            public DelayAdditionTask(long delay, int a, int b, DelayAdditionFuture future) {
                super();
                this.delay = delay;
                this.a = a;
                this.b = b;
                this.future = future;
            }

            @Override
            public void run() {
                try {
                    Thread.sleep(delay);
                    log.info("=========== add task, thrad: " + ThreadUtils.threadName());
                    Integer i = a + b;
                    //TODO 这里设置future为完成状态(正常执行完毕)
                    future.setSuccess(i);
                } catch (InterruptedException e) {
                    //TODO 这里设置future为完成状态(异常执行完毕)
                    future.setFailure(e.getCause());
                }
            }

        }
    }

    //只是把两个方法对外暴露
    static class DelayAdditionFuture extends AbstractFuture<Integer> {
        @Override
        public IFuture<Integer> setSuccess(Object result) {
            return super.setSuccess(result);
        }
        @Override
        public IFuture<Integer> setFailure(Throwable cause) {
            return super.setFailure(cause);
        }
    }
}
